<template>
  <div class="desk" data-desk-top="desk-top" :style="deskWallpaper" @contextmenu.prevent.stop="handleContextMenu">
    <div class="desk-inner">
      <desk-app />
    </div>
    <template v-for="item in runningTasksStore.$state.runningTasks" :key="item.appId">
      <teleport to="body">
        <transition-group name="win-create">
          <system-window
            v-for="child in item.list"
            :key="child.id"
            :title="child.title"
            :app-id="item.appId"
            :task-id="child.id"
            :position="[child.x, child.y]"
            :size="[child.width, child.height]"
            :min-size="child.minSize"
            :max-size="child.maxSize"
            :is-drag="child.isDrag"
            :is-full="child.isFull"
            :is-max="child.isMax"
            :is-min="child.isMin"
            :is-resize="child.isResize"
            :is-tray="child.isTray"
            :is-task-bar="child.isTaskBar"
            :is-top-bar="child.isSystemTopBar"
            :component-data="child.componentData"
            @min="handleTaskMin(item.appId, child.id)"
            @hidden="handleTaskHidden(item.appId, child.id)"
            @focus="handleTaskFocus(item.appId, child.id)"
            @close="handleCloseRunningTask(item.appId, child.id)"
            @min-max="handleMinMaxRunningTask(item.appId, child.id)"
            @resize-end="handleSystemModalResizeEnd($event, item.appId, child.id)"
            @drag-end="handleSystemModalDragEnd($event, item.appId, child.id)"
          >
            <component :is="taskAppComponent[child.component]" />
          </system-window>
        </transition-group>
      </teleport>
    </template>
    <teleport to="body">
      <system-context-menu
        v-model="contextMenuVisible"
        :menu="contextMenuList"
        :position="contextMenuPosition"
        ref="contextMenuDom"
        @menu-click="handleMenuClick"
      />
    </teleport>
    <teleport to="body">
      <transition name="lock">
        <desk-lock v-if="systemSettingStore.$state.deskLock" />
      </transition>
    </teleport>
    <task-modal v-model="systemProjectionVisible" path="to-left">
      <system-projection />
    </task-modal>
  </div>
</template>

<script setup lang="ts">
import QQ from '@/components/systemWindow/qq/qq.vue'
import Wps from '@/components/systemWindow/wps/wps.vue'
import Geek from '@/components/systemWindow/geek/geek.vue'
import KuGou from '@/components/systemWindow/kuGou/kuGou.vue'
import Folder from '@/components/systemWindow/folder/folder.vue'
import WeChat from '@/components/systemWindow/weChat/weChat.vue'
import Chrome from '@/components/systemWindow/chrome/chrome.vue'
import VsCode from '@/components/systemWindow/vsCode/vsCode.vue'
import DeskApp from '@/components/desk/deskApp.vue'
import DeskLock from '@/components/desk/deskLock.vue'
import SettingMenu from '@/components/systemWindow/systemSetting/settingMenu.vue'
import VideoPlayer from '@/components/systemWindow/videoPlayer/videoPlayer.vue'
import SystemWindow from '@/base/systemWindow/systemWindow.vue'
import SystemProjection from '@/components/taskBar/systemProjection.vue'
import SystemContextMenu from '@/components/desk/systemContextMenu.vue'
import { markRaw, reactive, ref } from 'vue'
import { useRunningTasksStore } from '@/stores/taskBar/runningTasks'
import { useSystemSettingStore } from '@/stores/desk/systemSetting'
import { systemMessage } from '@/base/systemMessage/systemMessageInstance'
import { useCreateTask, useSystemHotkeyHook } from '@/hooks/runningTaskHooks'
import { ContextMenu, EContextMenuEvent, EMenuRadio, useContextMenuStore } from '@/stores/desk/contextMenu'
import { BrowserChannelType, useBrowserHook } from '@/hooks/browserHooks'
import { browserChannel } from '@/utils/utils'
import { useDeskWallpaperHook } from '@/hooks/systemWindowHooks'
import type { Component, Raw } from 'vue'
import type { DeskAppComponent } from '@/stores/systemApp/deskApp'
import type { IContextMenu, IMenu } from '@/stores/desk/contextMenu'
import type { DeskAppIconSize, DeskAppIconSort } from '@/stores/desk/systemSetting'

useBrowserHook()

const { deskWallpaper } = useDeskWallpaperHook()
const { systemProjectionVisible } = useSystemHotkeyHook()
// 右键选中的菜单
let currentFocusContextMenuDom: HTMLElement
const runningTasksStore = useRunningTasksStore()
const contextMenuStore = useContextMenuStore()
const systemSettingStore = useSystemSettingStore()
// 是否显示右键菜单
const contextMenuVisible = ref<boolean>(false)
// 右键菜单DOM
const contextMenuDom = ref<HTMLElement>()
// 右键菜单列表 根据右键的位置 显示不同邮件
const contextMenuList = ref<IContextMenu[keyof IContextMenu]>([])
// 右键菜单的定位
const contextMenuPosition = reactive<number[]>([0, 0])
// 运行的弹窗组件
const taskAppComponent: { [k in string]: Raw<Component> } = {
  folder: markRaw(Folder),
  weChat: markRaw(WeChat),
  setting: markRaw(SettingMenu),
  geek: markRaw(Geek),
  QQ: markRaw(QQ),
  chrome: markRaw(Chrome),
  vsCode: markRaw(VsCode),
  kuGou: markRaw(KuGou),
  wps: markRaw(Wps),
  videoPlayer: markRaw(VideoPlayer)
}

const { handleCreateTask } = useCreateTask()

// 系统窗口拖动结束后
const handleSystemModalDragEnd = (
  ev: {
    x: number
    y: number
  },
  appId: string,
  id: string
) => {
  const { x, y } = ev
  runningTasksStore.setTaskPatch(appId, id, { x, y, endX: x, endY: y })
}

// 系统窗口关闭按键
const handleCloseRunningTask = (appId: string, id: string) => {
  runningTasksStore.closeTask(appId, id)
}

// 系统窗口最大化/最小化按键
const handleMinMaxRunningTask = (appId: string, id: string) => {
  runningTasksStore.setMinMaxTask(appId, id)
}

// 聚焦任务
const handleTaskFocus = (appId: string, id: string) => {
  runningTasksStore.checkedCurrentTask(appId, id)
}

// 最小化任务
const handleTaskMin = (appId: string, id: string) => {
  runningTasksStore.setTaskToMin(appId, id, true)
}

// 隐藏到系统托盘
const handleTaskHidden = (appId: string, id: string) => {
  runningTasksStore.setTaskToTray(appId, id, true)
}

// 拖动窗口大小
const handleSystemModalResizeEnd = (
  rect: {
    width: number
    height: number
    left: number
    top: number
  },
  appId: string,
  id: string
) => {
  const { left, top, width, height } = rect
  runningTasksStore.setTaskPatch(appId, id, { width, height, x: left, y: top, endX: left, endY: top })
}

// 右键
const handleContextMenu = (ev: MouseEvent) => {
  contextMenuStore.setDeskAppFullscreen()
  contextMenuPosition[0] = ev.x
  contextMenuPosition[1] = ev.y
  let dom = ev.target as HTMLElement
  while (!dom.dataset.deskApp && !dom.dataset.deskTop && dom.tagName.toLowerCase() !== 'body') {
    dom = dom.parentElement as HTMLElement
  }
  currentFocusContextMenuDom = dom
  const isApp = !!currentFocusContextMenuDom.dataset.deskApp
  const { appContextMenu, systemContextMenu } = ContextMenu.value
  contextMenuList.value = isApp ? appContextMenu : systemContextMenu
  contextMenuVisible.value = true
}

// 点击菜单事件
const handleMenuClick = (menu: IMenu) => {
  switch (menu.event) {
    case EContextMenuEvent.openApp: {
      const appId = currentFocusContextMenuDom.dataset.deskApp
      if (appId) handleCreateTask(appId as DeskAppComponent)
      break
    }
    case EContextMenuEvent.refresh:
      browserChannel.postMessage({ type: BrowserChannelType.refresh })
      location.reload()
      break
    case EContextMenuEvent.hiddenDeskApp:
      systemSettingStore.setDeskAppHidden()
      break
    case EContextMenuEvent.changeDeskAppSize:
    case EContextMenuEvent.changeDeskAppSort: {
      const find = contextMenuStore.findMenuData((item) => Boolean(item.isChecked && item.radio === menu.radio))
      if (find?.radioValue) {
        switch (find.radio) {
          case EMenuRadio.deskIconSizeRadio:
            systemSettingStore.setDeskAppSize(find.radioValue as DeskAppIconSize)
            break
          case EMenuRadio.deskIconSortRadio:
            systemSettingStore.setDeskAppSort(find.radioValue as DeskAppIconSort)
            break
        }
      }
      break
    }
    case EContextMenuEvent.showSetting:
      handleCreateTask('setting')
      break
    case EContextMenuEvent.checkRangeType:
      systemSettingStore.setDestAppRangeType()
      break
    case EContextMenuEvent.checkFullscreen:
      contextMenuStore.setDeskAppFullscreen(true)
      break
    case EContextMenuEvent.settingPersonality: {
      const data = handleCreateTask('setting')
      if (data) {
        runningTasksStore.setTaskPatch(data.appId, data.taskId, {
          componentData: {
            detailVisible: true,
            systemDetailIcon: 'wos-personality',
            menuIcon: 'wos-picture'
          }
        })
      }
      break
    }
    default:
      systemMessage.warning('功能开发中...')
      break
  }
}
</script>

<style scoped lang="scss">
.desk {
  padding-top: 6px;
  padding-bottom: 10px;

  .desk-inner {
    width: 100%;
    height: 100%;
  }
}
</style>
